home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* xpres 3
- /* SUMMARY
- /* communications port i/o
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* cico
- /* SYNOPSIS
- /* xopen()
- /*
- /* xclose()
- /*
- /* xread(dummy,buf,len)
- /* int dummy,len;
- /* char *buf;
- /*
- /* xwrite(dummy,buf,len)
- /* int dummy,len;
- /* char *buf;
- /*
- /* xioctl(flag)
- /* int flag;
- /* DESCRIPTION
- /* The functions in this module perform functions analogous
- /* to unix system calls, for the serial port of IBM-PC workalikes.
- /*
- /* xopen() initializes a serial port. Also needed under UNIX.
- /*
- /* xclose() closes a port.
- /*
- /* xread(), xwrite() do not use their first argument. Under UNIX
- /* one should use the standard read() and write() system calls.
- /*
- /* xioctl() enables xon/xoff flow control if its argument
- /* is nonzero. Not used under UNIX.
- /* SEE ALSO
- /* comport.asm, IBM-PC comm routines by Tim Pozar
- /* DIAGNOSTICS
- /* The read functions returns EOF in case of timeout; the write
- /* function never detects any failure.
- /* BUGS
- /* The xioctl() function is utterly primitive.
- /* AUTHOR(S)
- /* MS-DOS parts derived from uuslave software (John Gilmore)
- /* published on usenet early 1987. Bugs fixed & severely hacked by
- /*
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Sat Mar 28 23:01:43 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:02:59
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
-
- #include "defs.h"
- #include "params.h"
- #include "comm.h" /* baud rates, tty ports,... */
- #include "status.h"
- #include "sysdep.h" /* other system dependencies */
- #include "logs.h"
-
- #ifdef unix
- # include <sgtty.h>
- # include <signal.h>
- # include <setjmp.h>
- #endif
-
- #ifdef MSDOS
- # define B(x) (115200/(x))
- static int sigint();
- static void get_time();
-
- #endif
-
- typedef struct { /* baud-rate lookup table */
- char *name;
- int code;
- } Baud_table;
-
- Baud_table btable[] = {
- #ifdef unix
- "50", B50,
- "75", B75,
- "110", B110,
- "134", B134,
- "150", B150,
- "300", B300,
- "600", B600,
- "1200", B1200,
- "1800", B1800,
- "2400", B2400,
- "4800", B4800,
- "9600", B9600,
- #endif
- #ifdef MSDOS
- "50", B(50),
- "75", B(75),
- "110", B(110),
- "134", B(134),
- "150", B(150),
- "300", B(300),
- "600", B(600),
- "1200", B(1200),
- "1800", B(1800),
- "2400", B(2400),
- "4800", B(4800),
- "9600", B(9600),
- #endif
- 0, 0,
- };
-
- /* xopen - open communications port; parameters taken from setup table */
-
- xopen()
- {
- register Baud_table *bp;
-
- #ifdef unix
- struct sgttyb ttmode;
-
- #endif
-
- for (bp = btable; bp->name; bp++) /* look up baud rate */
- if (strcmp(bp->name, COMM_RATE) == 0)
- break;
- if (bp->name == 0) { /* bad baud rate in setup */
- debug(4) ("Invalid baud rate %s\n", COMM_RATE);
- exit(E_BADSETUP);
- }
- #ifdef unix
- if ((ttfd = open(COMM_LINE, 2)) < 0) { /* try to access port */
- debug(4) ("Cannot access %s\n", COMM_LINE);
- exit(E_BADSETUP);
- }
- #ifndef SIII
- if (ioctl(ttfd, TIOCEXCL)) /* exclusive access */
- exit(E_BADSETUP); /* not a terminal */
- #endif
- ioctl(ttfd, TIOCHPCL); /* hangup when done */
- gtty(ttfd, &ttmode); /* get port status */
- ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code; /* set baud rate */
- ttmode.sg_flags |= (RAW); /* raw mode */
- #ifdef SIII
- ttmode.sg_flags &= ~ECHO;
- #else
- ttmode.sg_flags &= ~(ECHO | TANDEM | CBREAK); /* no echo, crlf, flow
- * control */
- #endif
- stty(ttfd, &ttmode);
- #endif
-
- #ifdef MSDOS
- set_tty(bp->code); /* set baud rate, DTR */
- init_comm(); /* turn interrupts on */
- signal(SIGINT, sigint); /* must reset tty */
- inp_flush(); /* flush garbage */
- sleep(3);
- #endif
- }
-
- /* xclose - release the communications port */
-
- xclose()
- {
- #ifdef unix
- close(ttfd);
- #endif
-
- #ifdef MSDOS
- uninit_comm();
- #endif
- }
-
- /* xread - read from the serial port */
-
- #ifdef MSDOS
-
- xread(fd, buf, cnt)
- int fd;
- char *buf;
- register int cnt;
- {
- register char *p = buf;
- register int c;
-
- while (cnt > 0 && (c = xgetc()) != EOF) {
- *p++ = c;
- cnt--;
- }
- return (p - buf ? p - buf : -1);
- }
-
- #endif /* MSDOS xwrite() */
-
- /* xgetc - read one character from serial port */
-
- #ifdef unix
- jmp_buf xbuf;
-
- static timeout()
- { /* aux function for xgetc */
- longjmp(xbuf, 1);
- }
-
- xgetc()
- { /* return next char */
- char ch;
-
- if (setjmp(xbuf)) /* in case we time out */
- return (EOF); /* we just did */
- signal(SIGALRM, timeout); /* set timer response */
- alarm(BYTE_TIMEOUT); /* set timer */
-
- if (read(ttfd, &ch, 1) != 1) /* go wait for character */
- return(EOF);
- alarm(0); /* turn timer off */
- return (ch & 0377); /* successfull termination */
- }
-
- #endif /* unix xgetc() */
-
- #ifdef MSDOS
-
- xgetc()
- {
- char data;
-
- int i;
- unsigned s;
- TIME n;
-
- i = 0;
- get_time(&n);
- s = n.sec;
-
- /*
- * Implement timeouts by staring at the clock while we wait. When the
- * second hand moves, bump our counter. This is a lot easier than
- * figuring out the time when we'd time out (in hours, minutes, and
- * seconds!) and comparing against that, which is what people tend to do
- * in Unix where the time is just an integer number of seconds.
- */
- while (i < BYTE_TIMEOUT) {
- while (s == n.sec) {
- if (inp_cnt() != 0) {
- data = inp_char();
- return (data & 0xFF);
- }
- get_time(&n);
- }
- s = n.sec;
- ++i;
- }
- return (EOF);
- }
-
- /* xwrite - write buffer to serial port */
-
- xwrite(fd, buf, ctr)
- int fd;
- register char *buf;
- int ctr;
- {
- register int i = ctr;
-
- while (i-- > 0)
- outp_char(*buf++);
- return ctr;
- }
-
- /*
- * Routines specific to MS-DOS
- *
- * xioctl() enable xon/xoff
- * get_timer() read current time
- * sigint() clean up interrupt handler and exit
- * sleep() unix lookalike
- */
-
- /* xioctl - enable xon/xoff protocol */
-
- xioctl(flag)
- int flag;
- {
- set_xoff(flag); /* Enable (flag != 0) or
- * disable flow control */
- }
-
- /* sigint - restore terminal settings on dialout line */
-
- static int sigint()
- {
- uninit_comm();
- reset_tty();
- exit(0);
- }
-
- /* get_time - read time with dos call */
-
- static void get_time(n)
- TIME_PTR n;
- {
- union REGS inregs;
- union REGS outregs;
-
- inregs.h.ah = 0x2c; /* Please make a #define for
- * this, Tim */
-
- int86(0x21, &inregs, &outregs); /* Please #define the 0x21
- * too */
-
- n->hour = outregs.h.ch;
- n->minute = outregs.h.cl;
- n->sec = outregs.h.dh;
- n->hsec = outregs.h.dl;
- }
-
- #define get_sec(n) (get_time(&n),n.sec)
-
- sleep(x)
- int x;
- {
- TIME n; /* current time record */
- unsigned s = get_sec(n);
-
- while (x-- > 0) {
- while (s == get_sec(n))
- /* void */ ;
- s = n.sec;
- }
- }
-
- #endif /* MSDOS */
-